﻿using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json;
using Sunlight.Dispatch.Dal;
using Sunlight.Dispatch.Model;
using Sunlight.Dispatch.Tools;
using Sunlight.Dispatch.UI.Controls;
using Sunlight.Dispatch.UI.Extensions;
using Sunlight.Dispatch.UI.Properties;
using Sunlight.Dispatch.UI.TimeGranlarityForms;

namespace Sunlight.Dispatch.UI {
    public partial class InterfaceSettingFrm : BaseEditFrm {
        public InterfaceSettingFrm() {
            InitializeComponent();
            this.Load += InterfaceSettingFrm_Load;
        }

        private void InterfaceSettingFrm_Load(object sender, EventArgs e) {
            this.comboBoxDataBase.SelectedValueChanged += ComboBoxDataBase_SelectedValueChanged;
            var config = Utils.DeSerialize();
            if(config == null) {
                return;
            }
            using(var conn = new SQLiteConnection(string.Format($"Data Source={config.SqliteStoryPath};Version=3;"))) {
                conn.Open();
                var sqlExecute = "select Id,Name,ConnectString from ConnectStringConfigTb";
                var command = new SQLiteCommand(sqlExecute, conn);
                var reader = command.ExecuteReader();
                var source = new List<ConnectStringConfigTb>();
                while(reader.Read()) {
                    source.Add(new ConnectStringConfigTb {
                        Id = reader[0].ToString(),
                        Name = reader[1].ToString(),
                        ConnectString = reader[2].ToString()
                    });
                }

                //新增状态的接口配置，不允许编辑，必须在配置规则的情况下可以使用
                this.parameterFirstSettting.gbxIsRunControl.Enabled = false;
                this.comboBoxDataBase.DataSource = null;
                this.comboBoxDataBase.DataSource = source;
                this.comboBoxDataBase.DisplayMember = "Name";
                this.comboBoxDataBase.ValueMember = "ConnectString";

                var timeGranularityJson = Settings.Default.TimeGranularity;
                var stimeGranularity = JsonConvert.DeserializeObject<List<KeyValueItem>>(timeGranularityJson);
                this.comboBoxTimeType.DataSource = stimeGranularity;
                this.comboBoxTimeType.DisplayMember = "Value";
                this.comboBoxTimeType.ValueMember = "Key";
                if(stimeGranularity.Any(d => d.IsDefault)) {
                    var defaultKeyValue = stimeGranularity.First(d => d.IsDefault);
                    this.comboBoxTimeType.SelectedItem = defaultKeyValue;
                }
            }
        }

        private void ComboBoxDataBase_SelectedValueChanged(object sender, EventArgs e) {
            var item = comboBoxDataBase.SelectedItem as ConnectStringConfigTb;
            if(item == null)
                return;
            string msg;
            this.ConnectString = item.ConnectString;
            if(!Utils.IsCanConnect(out msg, item.ConnectString)) {
                MessageBoxEx.Show("该连接无法正常连接数据库，请确认", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                //清空选择
                this.comboBoxDataBase.SelectedItem = null;
                return;
            }
            this.parameterFirstSettting.Initialize(item.ConnectString);
        }

        private void btnSave_Click(object sender, EventArgs e) {
            var setting = this.parameterFirstSettting;
            var intf = this.DataContext as TIntf;
            if(intf == null)
                return;
            if(string.IsNullOrEmpty(setting.textBoxCode.Text)) {
                MessageBoxEx.Show(this, "编号不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(string.IsNullOrEmpty(setting.textBoxName.Text)) {
                MessageBoxEx.Show("名称不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(string.IsNullOrEmpty(setting.textBoxUpfunction.Text)) {
                MessageBoxEx.Show(this, "调用方法不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if(setting.comboBoxBusiness.SelectedItem == null) {
                MessageBoxEx.Show(this, "业务分类不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(setting.comboBoxReceive.SelectedItem == null) {
                MessageBoxEx.Show(this, "接收方不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(setting.comboBoxSend.SelectedItem == null) {
                MessageBoxEx.Show(this, "调用方不能为空", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            //该控件已经设置为只允许输入数字，这里可以直接转换判断即可
            if(string.IsNullOrEmpty(setting.textBoxThread.Text) || Convert.ToInt32(setting.textBoxThread.Text) <= 0 || Convert.ToInt32(setting.textBoxThread.Text) > 5) {
                MessageBoxEx.Show(this, "线程数不能为空，且必须大于0小于等于5", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(string.IsNullOrEmpty(setting.textBoxSysNumber.Text) || Convert.ToInt32(setting.textBoxSysNumber.Text) <= 0) {
                MessageBoxEx.Show(this, "同步数不能为空，且必须大于0", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            var business = setting.comboBoxBusiness.SelectedItem as TBusiness;
            var receive = setting.comboBoxReceive.SelectedItem as TSide;
            var send = setting.comboBoxSend.SelectedItem as TSide;
            if(business == null || receive == null || send == null)
                return;
            if(intf.TRule == null || !intf.TRule.Any()) {
                MessageBoxEx.Show(this, "调度规则配置不能为空，请配置", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            var context = new MonitorSettingDataContext(this.ConnectString);
            switch(this.EditState) {
                case EditState.新增:
                    intf.blnStep = setting.radioButtonAsync.Checked ? (short)YesOrNo.是 : (short)YesOrNo.否;
                    intf.BusinessCode = business.Code;
                    intf.Downer = receive.Code;
                    intf.DownFunction = setting.textBoxDownfunction.Text;
                    intf.MaxNum = Convert.ToInt32(setting.textBoxSysNumber.Text);
                    intf.Memo = setting.textBoxMemo.Text;
                    intf.Name = setting.textBoxName.Text;
                    intf.Code = setting.textBoxCode.Text;
                    intf.ThreadNum = Convert.ToInt32(setting.textBoxThread.Text);
                    intf.Uper = send.Code;
                    intf.UpFunction = setting.textBoxUpfunction.Text;

                    context.TIntf.InsertOnSubmit(intf);
                    break;
                case EditState.编辑:
                    var dbIntf = context.TIntf.FirstOrDefault(d => d.ID == intf.ID);
                    if(dbIntf != null) {
                        dbIntf.blnStep = setting.radioButtonAsync.Checked ? (short)YesOrNo.是 : (short)YesOrNo.否;
                        dbIntf.BusinessCode = business.Code;
                        dbIntf.Downer = receive.Code;
                        dbIntf.DownFunction = setting.textBoxDownfunction.Text;
                        dbIntf.MaxNum = Convert.ToInt32(setting.textBoxSysNumber.Text);
                        dbIntf.Memo = setting.textBoxMemo.Text;
                        dbIntf.Name = setting.textBoxName.Text;
                        dbIntf.Code = setting.textBoxCode.Text;
                        dbIntf.ThreadNum = Convert.ToInt32(setting.textBoxThread.Text);
                        dbIntf.Uper = send.Code;
                        dbIntf.UpFunction = setting.textBoxUpfunction.Text;
                    }
                    break;
            }

            try {
                context.SubmitChanges();
                context.Dispose();
                MessageBoxEx.Show(this, "保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            } catch(Exception ex) {
                MessageBoxEx.Show(this, ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnSendRule_Click(object sender, EventArgs e) {
            var timeCategory = this.comboBoxTimeType.SelectedItem as KeyValueItem;
            if(this.comboBoxTimeType.SelectedItem == null || timeCategory == null) {
                MessageBoxEx.Show("编辑发送规则，必须选择时间粒度", "提醒", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            var intf = this.DataContext as TIntf;
            if(intf == null || intf.TRule == null)
                return;
            if(intf.TRule.Any() && MessageBoxEx.Show(this, "已经配置过调用规则，是否重新配置？重新配置会清除已有的配置", "询问", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK) {
                return;
            }
            intf.TRule.Clear();
            BaseEditFrm frm;
            switch(timeCategory.Key) {
                case (int)TimeGranlarity.周:
                    frm = new SettingByWeekFrm();
                    var ruleWeek = frm.CreateObjectToEdit<TRule>(this.ConnectString);
                    ruleWeek.Kind = (int)TimeGranlarity.周;
                    ruleWeek.blnUp = (int)YesOrNo.是;
                    break;
                case (int)TimeGranlarity.日:
                    frm = new SettingByDayFrm();
                    var ruleDay = frm.CreateObjectToEdit<TRule>(this.ConnectString);
                    ruleDay.Kind = (int)TimeGranlarity.日;
                    ruleDay.blnUp = (int)YesOrNo.是;
                    break;
                case (int)TimeGranlarity.月:
                    frm = new SettingByMonthFrm();
                    var ruleMonth = frm.CreateObjectToEdit<TRule>(this.ConnectString);
                    ruleMonth.Kind = (int)TimeGranlarity.月;
                    ruleMonth.blnUp = (int)YesOrNo.是;
                    break;
                case (int)TimeGranlarity.年:
                    frm = new SettingByYearFrm();
                    var ruleYear = frm.CreateObjectToEdit<TRule>(this.ConnectString);
                    ruleYear.Kind = (int)TimeGranlarity.年;
                    ruleYear.blnUp = (int)YesOrNo.是;
                    break;
                default:
                    frm = new SettingByDayFrm();
                    var ruleDefault = frm.CreateObjectToEdit<TRule>(this.ConnectString);
                    ruleDefault.Kind = (int)TimeGranlarity.日;
                    ruleDefault.blnUp = (int)YesOrNo.是;
                    break;
            }
            frm.ExtendEvent += this.Frm_ExtendEvent;
            frm.MdiParent = this.MdiParent;
            frm.Show();
        }

        private void Frm_ExtendEvent(object sender, SubmittedEventArgs e) {
            var rule = sender as TRule;
            var intf = this.DataContext as TIntf;
            if(intf == null || rule == null)
                return;
            intf.TRule.Add(rule);
            //关闭此窗体
            e.Close();
        }
    }
}
